package edu.pku.sei.transformation.util.metamodelloader;

import java.io.File;

import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.core.MetaPackage;
import edu.pku.sei.modeler.model.core.MetaPrimitiveType;
import edu.pku.sei.transformation.editor.internal.TransformationEditorModelRoot;
import edu.pku.sei.transformation.editor.model.MetaModel;
import edu.pku.sei.transformation.editor.model.ModelFactory;

public abstract class AbstractMetaModelLoader {
	protected File xmiFile;
	protected edu.pku.sei.modeler.model.core.MetaModel projectModel;
	protected ModelFactory factory;

	protected MetaPrimitiveType booleanType;
	protected MetaPrimitiveType intType;
	protected MetaPrimitiveType doubleType;
	protected MetaPrimitiveType floatType;
	protected MetaPrimitiveType charType;
	protected MetaPrimitiveType stringType;
	protected MetaModel model;

	public static AbstractMetaModelLoader getLoader(String fileAddress,
			edu.pku.sei.modeler.model.core.MetaModel projectModel)
			throws Exception {
		if (fileAddress.endsWith(".ecore")) {
			return new EcoreMetaModelLoader(fileAddress, projectModel);
		} else if (fileAddress.endsWith(".xml")) {
			return new EMOFMetaModelLoader(fileAddress, projectModel);
		} else {
			throw new Exception("not support");
		}
	}

	public AbstractMetaModelLoader(String fileAddress,
			edu.pku.sei.modeler.model.core.MetaModel projectModel) {
		xmiFile = new File(fileAddress);
		this.projectModel = projectModel;
		try {
			this.factory = (ModelFactory) ModelRegistry.getRegistry()
					.getFactory(projectModel);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (FactoryNotFoundException e) {
			e.printStackTrace();
		}
		initPrimitiveType(projectModel);
	}

	public AbstractMetaModelLoader(File file,
			edu.pku.sei.modeler.model.core.MetaModel projectModel) {
		this.xmiFile = file;
		this.projectModel = projectModel;
		try {
			this.factory = (ModelFactory) ModelRegistry.getRegistry()
					.getFactory(projectModel);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (FactoryNotFoundException e) {
			e.printStackTrace();
		}
		initPrimitiveType(projectModel);
	}

	abstract public MetaModel getModel();

	protected void initPrimitiveType(
			edu.pku.sei.modeler.model.core.MetaModel model) {
		MetaPackage pkg = TransformationEditorModelRoot
				.getPrimitivePackage(projectModel);
		for (Object type : pkg.getNamedElements()) {
			if (type instanceof MetaPrimitiveType) {
				MetaPrimitiveType primitiveType = (MetaPrimitiveType) type;
				if ("boolean".equals(primitiveType.getName()))
					this.booleanType = primitiveType;
				else if ("int".equals(primitiveType.getName()))
					this.intType = primitiveType;
				else if ("double".equals(primitiveType.getName()))
					this.doubleType = primitiveType;
				else if ("float".equals(primitiveType.getName()))
					this.floatType = primitiveType;
				else if ("char".equals(primitiveType.getName()))
					this.charType = primitiveType;
				else if ("String".equals(primitiveType.getName()))
					this.stringType = primitiveType;
			}

		}
	}

	public void setModel(MetaModel model) {
		this.model = model;
	}
}
